/*
  Copyright (C) 2011, Kyungjoo Kim
  
  This file is part of UHM (Unassembled HyperMatrix) sparse direct solver.
  
  All rights reserved.

  This library is free software; you can redistribute it and/or
  modify it under the terms of the GNU Lesser General Public
  License as published by the Free Software Foundation; either
  version 2.1 of the License, or (at your option) any later version.
  
  This library is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  Lesser General Public License for more details.
  
  You should have received a copy of the GNU Lesser General Public
  License along with this library; if not, write to the Free Software
  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
  Also add information on how to contact you by electronic and paper mail.
  
  
  Kyungjoo Kim
  iamkyungjoo@gmail.com
*/
#include "uhm.hxx"

#include "dmumps_c.h"
#include "zmumps_c.h"

#include "uhm/interf/mumps.hxx"
#include "uhm/wrapper/mumps_fort.hxx"

//----------------------------------------------------------------------
// FORTRAN INTERFACE
//----------------------------------------------------------------------

// ** MUMPS
//----------------------------------------------------------------------
void UHM_C2F(uhm_mesh_export_matrix_mumps)  ( uhm_fort_p   *mesh,
                                              uhm_fort_p   *mumps,
                                              uhm_fort_int *n_rhs,
                                              uhm_fort_int *is_sym ) {
  uhm::Mesh m = (uhm::Mesh)( *mesh );
  uhm::interf::Mumps mp = (uhm::interf::Mumps)( *mumps );
  m->export_matrix(mp, *n_rhs, *is_sym);
}

void UHM_C2F(uhm_mumps_create)              ( uhm_fort_p   *mumps,
                                              uhm_fort_int *datatype ) {
  uhm::interf::Mumps mp = new uhm::interf::Mumps_( *datatype );
  *mumps = (uhm_fort_p)mp;
}

void UHM_C2F(uhm_mumps_delete)              ( uhm_fort_p   *mumps ) {
  uhm::interf::Mumps mp = (uhm::interf::Mumps)( *mumps );
  delete mp;
}

void UHM_C2F(uhm_mumps_is_complex)          ( uhm_fort_p   *mumps,
                                              uhm_fort_int *flag) {
  uhm::interf::Mumps mp = (uhm::interf::Mumps)( *mumps );
  if (mp->is_complex()) *flag = 1;
  else *flag = 0;
}

void UHM_C2F(uhm_mumps_set_show_n_rhs)      ( uhm_fort_p   *mumps,
                                              uhm_fort_int *show_n_rhs) {
  uhm::interf::Mumps mp = (uhm::interf::Mumps)( *mumps );
  mp->set_show_n_rhs(*show_n_rhs);
}

void UHM_C2F(uhm_mumps_set_par)             ( uhm_fort_p   *mumps,
                                              uhm_fort_int *par) {
  uhm::interf::Mumps mp = (uhm::interf::Mumps)( *mumps );
  mp->set_par(*par);
}

void UHM_C2F(uhm_mumps_set_sym)             ( uhm_fort_p   *mumps,
                                              uhm_fort_int *sym) {
  uhm::interf::Mumps mp = (uhm::interf::Mumps)( *mumps );
  mp->set_sym(*sym);
}

void UHM_C2F(uhm_mumps_set_comm)            ( uhm_fort_p   *mumps,
                                              uhm_fort_int *comm) {
  uhm::interf::Mumps mp = (uhm::interf::Mumps)( *mumps );
  mp->set_comm(*comm);
}

void UHM_C2F(uhm_mumps_set_job)             ( uhm_fort_p   *mumps,
                                              uhm_fort_int *job) {
  uhm::interf::Mumps mp = (uhm::interf::Mumps)( *mumps );
  mp->set_job(*job);
}

void UHM_C2F(uhm_mumps_run)                 ( uhm_fort_p   *mumps ) {
  uhm::interf::Mumps mp = (uhm::interf::Mumps)( *mumps );
  mp->run();
}

void UHM_C2F(uhm_mumps_set_icntl)           ( uhm_fort_p   *mumps,
                                              uhm_fort_int *idx,
                                              uhm_fort_int *val ) {
  uhm::interf::Mumps mp = (uhm::interf::Mumps)( *mumps );
  mp->set_icntl( *idx, *val );
}

void UHM_C2F(uhm_mumps_set_cntl)             ( uhm_fort_p   *mumps,
                                                uhm_fort_int *idx,
                                                uhm_fort_double *val ) {
  uhm::interf::Mumps mp = (uhm::interf::Mumps)( *mumps );
  mp->set_cntl( *idx, *val );
}

void UHM_C2F(uhm_mumps_get_icntl)             ( uhm_fort_p   *mumps,
                                                uhm_fort_int *idx,
                                                uhm_fort_int *val ) {
  uhm::interf::Mumps mp = (uhm::interf::Mumps)( *mumps );
  *val = mp->get_icntl( *idx );
}

void UHM_C2F(uhm_mumps_get_cntl)              ( uhm_fort_p   *mumps,
                                                uhm_fort_int *idx,
                                                uhm_fort_double *val ) {
  uhm::interf::Mumps mp = (uhm::interf::Mumps)( *mumps );
  *val = mp->get_cntl( *idx );
}

void UHM_C2F(uhm_mumps_get_info)              ( uhm_fort_p   *mumps,
                                                uhm_fort_int *idx,
                                                uhm_fort_int *val ) {
  uhm::interf::Mumps mp = (uhm::interf::Mumps)( *mumps );
  *val = mp->get_info( *idx );
}

void UHM_C2F(uhm_mumps_get_infog)             ( uhm_fort_p   *mumps,
                                                uhm_fort_int *idx,
                                                uhm_fort_int *val ) {
  uhm::interf::Mumps mp = (uhm::interf::Mumps)( *mumps );
  *val = mp->get_infog( *idx );
}

void UHM_C2F(uhm_mumps_get_rinfo)             ( uhm_fort_p   *mumps,
                                                uhm_fort_int *idx,
                                                uhm_fort_double *val ) {
  uhm::interf::Mumps mp = (uhm::interf::Mumps)( *mumps );
  *val = mp->get_rinfo( *idx );
}

void UHM_C2F(uhm_mumps_get_rinfog)            ( uhm_fort_p   *mumps,
                                                uhm_fort_int *idx,
                                                uhm_fort_double *val ) {
  uhm::interf::Mumps mp = (uhm::interf::Mumps)( *mumps );
  *val = mp->get_rinfog( *idx );
}



void UHM_C2F(uhm_mumps_init)                ( uhm_fort_p   *mumps ) {
  uhm::interf::Mumps mp = (uhm::interf::Mumps)( *mumps );
  mp->init();
}

void UHM_C2F(uhm_mumps_analyze)             ( uhm_fort_p   *mumps ) {
  uhm::interf::Mumps mp = (uhm::interf::Mumps)( *mumps );
  mp->analyze();
}

void UHM_C2F(uhm_mumps_decompose)           ( uhm_fort_p   *mumps ) {
  uhm::interf::Mumps mp = (uhm::interf::Mumps)( *mumps );
  mp->decompose();
}

void UHM_C2F(uhm_mumps_solve)               ( uhm_fort_p   *mumps ) {
  uhm::interf::Mumps mp = (uhm::interf::Mumps)( *mumps );
  mp->solve();
}

void UHM_C2F(uhm_mumps_export_matrix_uhm)   ( uhm_fort_p   *mumps,
                                              uhm_fort_p   *mesh ) {
  uhm::interf::Mumps mp = (uhm::interf::Mumps)( *mumps );
  uhm::Mesh m = (uhm::Mesh)( *mesh );
  mp->export_matrix(m);
}

void UHM_C2F(uhm_mumps_finalize)            ( uhm_fort_p   *mumps ) {
  uhm::interf::Mumps mp = (uhm::interf::Mumps)( *mumps );
  mp->finalize();
}

